package cn.bonoon.kernel.security;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;

import cn.bonoon.entities.plugins.FlagType;
import cn.bonoon.kernel.support.IOperator;

/**
 * <pre>
 * 已经登录的用户信息，该信息将会存放于session里
 * </pre>
 * 
 * <pre>
 * 2013-11-28 : 新定义的登录用户信息，不再存放用户的操作权限了，当前用户操作权限的处理
 * 使用实时的读取数据库的方式
 * </pre>
 * 
 * @author jackson
 * @version 2.1 对登录用户存放的修改进行重新定义
 */
public final class LogonUser extends User implements IOperator {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5390973627983792802L;
	private Long id;
	private String displayName;
	//一定时间后强制刷新菜单
	private long lastUpdate;
	private FlagType flagType;
	private final Map<String, Object> attributes;
	
	/**
	 * 如果登录成功，则可以跳转到的界面
	 */
//	private final String targetMenu;
	
	/**
	 * 该账户属于一个企业,组织或其它团体之类的.
	 */
	private final long ownerId; 
	
	/**
	 * 在用户登录成功后，随机生成整数
	 */
//	private final int seed;
	
	private boolean needChangePwd;

	public LogonUser(Long id, String loginName, String password, boolean enabled,
			Collection<? extends GrantedAuthority> authorities, long ownerId) {
		super(loginName, password, enabled, true, true, true, authorities);
		this.id = id;
		this.ownerId = ownerId;
		this.attributes = new HashMap<String, Object>();
//		this.seed = Math.abs(new Random().nextInt());
	}
	
	public User initPrivileges(String displayName, boolean needChangePwd, FlagType flagType){
		this.displayName = displayName;
		this.needChangePwd = needChangePwd;
		this.flagType = flagType;
		this.lastUpdate = System.currentTimeMillis();
		return this;
	}
	
	public boolean checkTimeout(long timeout){
		return timeout + lastUpdate < System.currentTimeMillis();
	}

	public LogonUser set(String name, Object obj) {
		attributes.put(name, obj);
		return this;
	}

	public Object get(String name) {
		return attributes.get(name);
	}

	public <T> T get(String name, Class<T> cls) {
		return cls.cast(attributes.get(name));
	}
	
	public Long getLong(String name){
		Object obj = attributes.get(name);
		if(null == obj)return -1L;
		if(obj instanceof Long)return (Long)obj;
		return Long.valueOf(obj.toString());
	}
	
	public boolean contains(String name){
		return attributes.containsKey(name);
	}

	public Integer getInt(String name){
		Object obj = attributes.get(name);
		if(null == obj)return -1;
		if(obj instanceof Integer)return (Integer)obj;
		return Integer.valueOf(obj.toString());
	}
	
	public String getString(String name){
		Object obj = attributes.get(name);
		if(null == obj) return null;
		return obj.toString();
	}
	
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

//	public PrivilegeHandler privilege() {
//		return privilege;
//	}

//	public boolean checkFlag(FlagType ft) {
//		return flagType.equals(ft);
//	}
//	
//	public boolean checkFlag(FlagType ft, FlagType ft2) {
//		return flagType.equals(ft) || flagType.equals(ft2);
//	}
//
//	public boolean checkFlag(FlagType... fts) {
//		for (FlagType ft : fts) {
//			if(ft.equals(flagType)) return true;
//		}
//		return false;
//	}
//	
	public boolean allowAccess(){
		return flagType != FlagType.CUSTOM && flagType != FlagType.GUEST;
	}

//	public String getTargetMenu() {
//		return targetMenu;
//	}

	public String getDisplayName() {
		return displayName;
	}

	public Long getOwnerId() {
		return ownerId;
	}
	
	@Override
	public long toOwnerId() {
		return ownerId;
	}

	public boolean isSuper() {
		return flagType == FlagType.SUPER;
	}
	
	public boolean isAdmin(){
		return flagType == FlagType.ADMIN;
	}
	
	public boolean isUser(){
		return flagType == FlagType.USER;
	}
	
	/**
	 * 加密
	 * @param id
	 * @return
	 */
	public final Long encryptId(Long id){
		return id;
	}
	public final long encryptId(long id){
		return id;
	}
	
	/**
	 * 解密
	 * @param id
	 * @return
	 */
	public final Long decryptId(Long id){
		return id;
	}
	public final long decryptId(long id){
		return id;
	}

	public boolean needChangePwd() {
		return needChangePwd;
	}

	public void changePwd() {
		this.needChangePwd = false;
	}
	
	public static void main(String[] args){
		long seed = new Random().nextLong();//0x7FFFFFFF;//System.currentTimeMillis();
		System.out.println("seed:" + seed);
		Long id = 5011l;
		System.out.println("id:" + id);
		id = seed ^ id;
		System.out.println("encrypt id:" + id);
		id = seed ^ id;
		System.out.println("decrypt id:" + id);
	}
	
	@Override
	public int hashCode() {
		return id.hashCode();
	}
	
	@Override
	public boolean equals(Object rhs) {
		if(rhs instanceof LogonUser){
			return id.equals(((LogonUser) rhs).id);
		}
		return super.equals(rhs);
	}
}
